using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml;

namespace WordToSharePoint
{
    public class ImportWord : LayoutsPageBase
    {        
        private static readonly string version = "v 2.1";
        protected DropDownList ddlWebPageLibraries;
        protected DropDownList ddlDocs;
        protected DropDownList ddlImages;
        protected TextBox textBoxDimension;
        protected CheckBox checkBoxWordDocuments;
        protected CheckBox checkBoxImageResize;
        protected CheckBox checkBoxAsHTML;
        protected Button cmdImportWord;
        protected Button cmdImportAll;
        protected Literal litCurrentLocation;
        protected Literal litOutput;
                                   
        protected override void OnLoad(EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                string status = string.Empty;
                SPWeb site = SPContext.Current.Web;

                try
                {
                    checkBoxAsHTML.Checked = true;
                    status = version;
                    DisplaySiteLists(site);
                    DisplayDocuments(site, true);
                    DisplayImageFolders(site);                    
                }
                catch (Exception ex)
                {
                    status = string.Format("{0} :: {1}", ex.Message, ex.StackTrace);
                }
                finally
                {
                    site.Dispose();
                }

                litCurrentLocation.Text = status;
            }
        }


        private void DisplaySiteLists(SPWeb site)
        {
            ddlWebPageLibraries.Items.Clear();
            List<SPDocumentLibrary> matchingLibraries = GetWebLibraries(site, "WebPageLibrary");
            matchingLibraries.Sort(delegate(SPDocumentLibrary p1, SPDocumentLibrary p2) { return p1.Title.CompareTo(p2.Title); });
            foreach (SPDocumentLibrary library in matchingLibraries)
            {
                ddlWebPageLibraries.Items.Add(new ListItem(library.Title, library.RootFolder.Name));
            }
        }

        private void DisplayDocuments(SPWeb site, bool showDocxOnly)
        {
            ddlDocs.Items.Clear();
            List<SPFile> fileList = GetSPFiles(site, showDocxOnly);

            foreach (SPFile file in fileList)
            {
                ddlDocs.Items.Add(new ListItem(file.Name, file.Url));
            }
        }

        private List<SPFile> GetSPFiles(SPWeb site, bool showDocxOnly)
        {
            List<SPDocumentLibrary> matchingLibraries = GetWebLibraries(site, "DocumentLibrary");

            List<SPFile> fileList = new List<SPFile>();
            foreach (SPDocumentLibrary library in matchingLibraries)
            {
                SPFileCollection files = library.RootFolder.Files;
                foreach (SPFile file in files)
                {
                    if (!showDocxOnly || file.Name.ToLower().Contains("docx"))
                        fileList.Add(file);
                }
            }

            fileList.Sort(delegate(SPFile p1, SPFile p2) { return p1.Name.CompareTo(p2.Name); });

            return fileList;
        }

        private void DisplayImageFolders(SPWeb site)
        {
            ddlImages.Items.Clear();
            List<SPDocumentLibrary> matchingLibraries = GetWebLibraries(site, "PictureLibrary");
            matchingLibraries.Sort(delegate(SPDocumentLibrary p1, SPDocumentLibrary p2) { return p1.Title.CompareTo(p2.Title); });

            foreach (SPDocumentLibrary library in matchingLibraries)
            {
                ddlImages.Items.Add(new ListItem(library.Title, library.RootFolder.Name));
            }            
        }

        private List<SPDocumentLibrary> GetWebLibraries(SPWeb site, string libraryTypeName)
        {
            List<SPDocumentLibrary> matchingLibraries = new List<SPDocumentLibrary>();

            SPListCollection lists = site.Lists;

            foreach (SPList splist in lists)
            {
                if (splist.BaseType == SPBaseType.DocumentLibrary)
                {
                    SPDocumentLibrary docLib = (SPDocumentLibrary)splist;
                    Guid templateGuid = docLib.TemplateFeatureId;
                    if (templateGuid != Guid.Empty)
                    {
                        SPFeature siteFeature = site.Features[templateGuid];
                        string featureName = siteFeature.Definition.DisplayName;
                        if (featureName == libraryTypeName)
                        {
                            matchingLibraries.Add(docLib);
                        }
                    }
                }
            }

            return matchingLibraries;
        }

        public void ExecuteTransformation()
        {
            List<string> runningLog = new List<string>();
            using (SPWeb web = SPContext.Current.Web)
            {
                List<SPFile> fileList = null;

                if (checkBoxWordDocuments.Checked)
                {
                    fileList = GetSPFiles(web, true);
                }
                else
                {
                    fileList = new List<SPFile>();
                    SPFile file = web.GetFile(ddlDocs.SelectedValue);
                    fileList.Add(file);
                }

                foreach (SPFile file in fileList)
                {
                    DateTime started = DateTime.Now;
                    runningLog.Add(string.Format("INFO:: Import Started {0} :: File: {1}", DateTime.Now.ToString(), file.Name));
                    List<string> eventLog = ImportWordDocument(file, web);
                    eventLog.Add(version);
                    runningLog.AddRange(eventLog);
                    runningLog.Add(string.Format("INFO:: Import Complete {0} :: File: {1} :: Time Taken {2}", DateTime.Now.ToString(), file.Name, DateTime.Now.Subtract(started).ToString()));
                }
            }

            litOutput.Text = string.Empty;
            foreach (string entry in runningLog)
            {
                litOutput.Text = string.Format("{0}{1}{2}", litOutput.Text, "</br>", entry);
            }
        }

        protected List<string> ImportWordDocument(SPFile file, SPWeb web)
        {
            List<string> eventLog = null;
            string xsl = (checkBoxAsHTML.Checked) ? XSLFileConduit.GetMinimalXSL() : XSLFileConduit.GetRichHTMLXSL();
            WordprocessingDocument pack = WordprocessingDocument.Open(file.OpenBinaryStream(), true);

            try
            {          
                DocumentHandler handler = new DocumentHandler(file);

                eventLog = handler
                    .Process(
                        xsl, 
                        web.Url,                         
                        ddlWebPageLibraries.SelectedValue, 
                        ddlImages.SelectedValue, 
                        int.Parse(textBoxDimension.Text),
                        checkBoxImageResize.Checked
                    );

            }
            catch (Exception ex)
            {
                eventLog.Add(string.Format("ERROR: {0} :: {1}", ex.Message,ex.StackTrace));                
            }
            finally
            {
                
            }
            return eventLog;
        }            

        protected void cmdImportWord_Click(object sender, EventArgs e)
        {
            ExecuteTransformation();
        }

        protected void checkBoxImageResize_CheckChanged(object sender, EventArgs e)
        {
            textBoxDimension.Enabled = checkBoxImageResize.Checked;
        }

        protected void checkBoxWordDocuments_CheckChanged(object sender, EventArgs e)
        {
            ddlDocs.Enabled = (!checkBoxWordDocuments.Checked);            
        }        
    }
}
